/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;

namespace FaceCat {
    /// <summary>
    /// 日期层
    /// </summary>
    public class DayDiv {
        /// <summary>
        /// 创建日期层
        /// </summary>
        public DayDiv(FCCalendar calendar) {
            m_calendar = calendar;
            onLoad();
        }

        /// <summary>
        /// 点击时的上月的行
        /// </summary>
        public int m_am_ClickRowFrom;

        /// <summary>
        /// 点击时的当月的行
        /// </summary>
        public int m_am_ClickRowTo;

        /// <summary>
        /// 动画的方向
        /// </summary>
        public int m_am_Direction;

        /// <summary>
        /// 动画当前帧数
        /// </summary>
        public int m_am_Tick;

        /// <summary>
        /// 动画总帧数
        /// </summary>
        public int m_am_TotalTick = 40;

        /// <summary>
        /// 日期层的集合
        /// </summary>
        public ArrayList<DayButton> m_dayButtons = new ArrayList<DayButton>();

        /// <summary>
        /// 动画日期层的集合
        /// </summary>
        public ArrayList<DayButton> m_dayButtons_am = new ArrayList<DayButton>();

        public FCCalendar m_calendar;

        /// <summary>
        /// 获取日历视图
        /// </summary>
        public virtual FCCalendar getCalendar()
        {
            return m_calendar;
        }

        /// <summary>
        /// 设置日历视图
        /// </summary>
        public virtual void setCalendar(FCCalendar value)
        {
            m_calendar = value;
        }

        /// <summary>
        /// 销毁方法
        /// </summary>
        public virtual void delete() {
            m_dayButtons.clear();
            m_dayButtons_am.clear();
        }

        /// <summary>
        /// 隐藏
        /// </summary>
        public virtual void hide() {
            int dayButtonSize = m_dayButtons.size();
            for (int i = 0; i < dayButtonSize; i++) {
                DayButton dayButton = m_dayButtons.get(i);
                dayButton.setVisible(false);
            }
        }

        /// <summary>
        /// 触摸点击方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public void onClick(FCTouchInfo touchInfo) {
            FCPoint mp = touchInfo.m_firstPoint;
            int dayButtonsSize = m_dayButtons.size();
            for (int i = 0; i < dayButtonsSize; i++) {
                DayButton dayButton = m_dayButtons.get(i);
                if (dayButton.isVisible()) {
                    FCRect bounds = dayButton.getBounds();
                    if (mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom) {
                        dayButton.onClick(touchInfo);
                        return;
                    }
                }
            }
            int dayButtonAmSize = m_dayButtons_am.size();
            for (int i = 0; i < dayButtonAmSize; i++) {
                DayButton dayButton = m_dayButtons_am.get(i);
                if (dayButton.isVisible()) {
                    FCRect bounds = dayButton.getBounds();
                    if (mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom) {
                        dayButton.onClick(touchInfo);
                        return;
                    }
                }
            }
        }

        /// <summary>
        /// 添加视图方法
        /// </summary>
        public virtual void onLoad() {
            if (m_calendar != null) {
                FCHost host = m_calendar.getNative().getHost();
                if (m_dayButtons.size() == 0 || m_dayButtons_am.size() == 0) {
                    m_dayButtons.clear();
                    m_dayButtons_am.clear();
                    for (int i = 0; i < 42; i++) {
                        DayButton dayButton = m_calendar.createDayButton();
                        m_dayButtons.add(dayButton);
                        DayButton dayButtonAm = m_calendar.createDayButton();
                        dayButtonAm.setVisible(false);
                        m_dayButtons_am.add(dayButtonAm);
                    }
                }
            }
        }

        /// <summary>
        /// 重绘方法
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="clipRect">裁剪区域</param>
        public virtual void onPaint(FCPaint paint, FCRect clipRect) {
            int dayButtonsSize = m_dayButtons.size();
            for (int i = 0; i < dayButtonsSize; i++) {
                DayButton dayButton = m_dayButtons.get(i);
                if (dayButton.isVisible()) {
                    FCRect bounds = dayButton.getBounds();
                    dayButton.onPaintBackGround(paint, bounds);
                    dayButton.onPaintForeground(paint, bounds);
                    dayButton.onPaintBorder(paint, bounds);
                }
            }
            int dayButtonAmSize = m_dayButtons_am.size();
            for (int i = 0; i < dayButtonAmSize; i++) {
                DayButton dayButton = m_dayButtons_am.get(i);
                if (dayButton.isVisible()) {
                    FCRect bounds = dayButton.getBounds();
                    dayButton.onPaintBackGround(paint, bounds);
                    dayButton.onPaintForeground(paint, bounds);
                    dayButton.onPaintBorder(paint, bounds);
                }
            }
        }

        /// <summary>
        /// 重置日期图层
        /// </summary>
        /// <param name="state">状态</param>
        public virtual void onResetDiv(int state) {
            if (m_calendar != null) {
                int size = 0;
                CMonth thisMonth = m_calendar.getMonth();
                CMonth lastMonth = m_calendar.getLastMonth(thisMonth.getYear(), thisMonth.getMonth());
                CMonth nextMonth = m_calendar.getNextMonth(thisMonth.getYear(), thisMonth.getMonth());
                int left = 0;
                int headHeight = m_calendar.getHeadDiv().getHeight();
                int top = headHeight;
                int width = m_calendar.getWidth();
                int height = m_calendar.getHeight();
                height -= m_calendar.getTimeDiv().getHeight();
                int dayButtonHeight = height - top;
                if (dayButtonHeight < 1) dayButtonHeight = 1;
                int toY = 0;
                ArrayList<DayButton> dayButtons = new ArrayList<DayButton>();
                if (m_am_Direction == 1) {
                    toY = dayButtonHeight * m_am_Tick / m_am_TotalTick;
                    if (state == 1) {
                        thisMonth = nextMonth;
                        lastMonth = m_calendar.getLastMonth(thisMonth.getYear(), thisMonth.getMonth());
                        nextMonth = m_calendar.getNextMonth(thisMonth.getYear(), thisMonth.getMonth());
                    }
                }
                else if (m_am_Direction == 2) {
                    toY = -dayButtonHeight * m_am_Tick / m_am_TotalTick;
                    if (state == 1) {
                        thisMonth = lastMonth;
                        lastMonth = m_calendar.getLastMonth(thisMonth.getYear(), thisMonth.getMonth());
                        nextMonth = m_calendar.getNextMonth(thisMonth.getYear(), thisMonth.getMonth());
                    }
                }
                if (state == 0) {
                    dayButtons = m_dayButtons;
                }
                else if (state == 1) {
                    dayButtons = m_dayButtons_am;
                }
                int dheight = dayButtonHeight / 6;
                HashMap<int, CDay> days = thisMonth.getDays();
                CDay firstDay = days.get(1);
                int startDayOfWeek = (int)new DateTime(firstDay.getYear(), firstDay.getMonth(), firstDay.getDay()).DayOfWeek;
                int buttonSize = dayButtons.size();
                for (int i = 0; i < buttonSize; i++) {
                    if (i == 35) {
                        dheight = height - top;
                    }
                    DayButton dayButton = dayButtons.get(i);
                    int vOffSet = 0;
                    if (state == 1) {
                        if (m_am_Tick > 0) {
                            dayButton.setVisible(true);
                            if (m_am_Direction == 1) {
                                vOffSet = toY - dayButtonHeight;
                            }
                            else if (m_am_Direction == 2) {
                                vOffSet = toY + dayButtonHeight;
                            }
                        }
                        else {
                            dayButton.setVisible(false);
                            continue;
                        }
                    }
                    else {
                        vOffSet = toY;
                    }
                    if ((i + 1) % 7 == 0) {
                        FCPoint dp = new FCPoint(left, top + vOffSet);
                        FCSize ds = new FCSize(width - left, dheight);
                        if (!m_calendar.m_showWeekend)
                        {
                            ds.cx = 0;
                        }
                        dayButton.setBounds(new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy));
                        left = 0;
                        if (i != 0 && i != size - 1) {
                            top += dheight;
                        }
                    }
                    else {
                        FCPoint dp = new FCPoint(left, top + vOffSet);
                        FCSize ds = new FCSize(width / 7 + ((i + 1) % 7) % 2, dheight);
                        if (!m_calendar.m_showWeekend)
                        {
                            if ((i + 1) % 7 == 1)
                            {
                                ds.cx = 0;
                            }
                            else
                            {
                                ds.cx = width / 5 + ((i + 1) % 5) % 2;
                            }
                        }
                        dayButton.setBounds(new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy));
                        left += ds.cx;
                    }
                    CDay cDay = null;
                    dayButton.setInThisMonth(false);
                    if (i >= startDayOfWeek && i <= startDayOfWeek + days.size() - 1) {
                        cDay = days.get(i - startDayOfWeek + 1);
                        dayButton.setInThisMonth(true);
                    }
                    else if (i < startDayOfWeek) {
                        cDay = lastMonth.getDays().get(lastMonth.getDays().size() - startDayOfWeek + i + 1);
                    }
                    else if (i > startDayOfWeek + days.size() - 1) {
                        cDay = nextMonth.getDays().get(i - startDayOfWeek - days.size() + 1);
                    }
                    int day = cDay.getDay();
                    dayButton.setDay(cDay);
                    if (state == 0 && dayButton.getDay() != null && dayButton.getDay() == m_calendar.getSelectedDay()) {
                        dayButton.setSelected(true);
                    }
                    else {
                        dayButton.setSelected(false);
                    }
                }
            }
        }

        /// <summary>
        /// 秒表触发方法
        /// </summary>
        public virtual void onTimer() {
            if (m_am_Tick > 0) {
                m_am_Tick = (int)((double)m_am_Tick * 2 / 3);
                if (m_calendar != null) {
                    m_calendar.update();
                    m_calendar.invalidate();
                }
            }
        }

        /// <summary>
        /// 选中日期
        /// </summary>
        /// <param name="selectedDay">日期</param>
        public void selectedDay(CDay selectedDay) {
            if (m_calendar != null) {
                CMonth m = m_calendar.getYears().getYear(selectedDay.getYear()).getMonths().get(selectedDay.getMonth());
                CMonth thisMonth = m_calendar.getMonth();
                if (m != thisMonth) {
                    if (thisMonth.getYear() * 12 + thisMonth.getMonth() > m.getYear() * 12 + m.getMonth()) {
                        m_am_Direction = 2;
                    }
                    else {
                        m_am_Direction = 1;
                    }
                    int dayButtonSize = m_dayButtons.size();
                    for (int i = 0; i < dayButtonSize; i++) {
                        DayButton dayButton = m_dayButtons.get(i);
                        if ((m_am_Direction == 1 && dayButton.getDay() == thisMonth.getFirstDay())
                            || m_am_Direction == 2 && dayButton.getDay() == thisMonth.getLastDay()) {
                            m_am_ClickRowFrom = i / 7;
                            if (i % 7 != 0) {
                                m_am_ClickRowFrom += 1;
                            }
                        }
                    }
                    m_calendar.setMonth(m);
                    onResetDiv(0);
                    int mdayButtonSize = m_dayButtons_am.size();
                    for (int i = 0; i < mdayButtonSize; i++) {
                        DayButton dayButtonAm = m_dayButtons_am.get(i);
                        if ((m_am_Direction == 1 && dayButtonAm.getDay() == m.getLastDay())
                        || (m_am_Direction == 2 && dayButtonAm.getDay() == m.getFirstDay())) {
                            m_am_ClickRowTo = i / 7;
                            if (i % 7 != 0) {
                                m_am_ClickRowTo += 1;
                            }
                        }
                    }
                    if (m_calendar.useAnimation()) {
                        m_am_Tick = m_am_TotalTick;
                    }
                }
                else {
                    int dayButtonSize = m_dayButtons.size();
                    for (int i = 0; i < dayButtonSize; i++) {
                        DayButton dayButton = m_dayButtons.get(i);
                        if (dayButton.getDay() != selectedDay) {
                            dayButton.setSelected (false);
                        }
                    }
                    m_calendar.setMonth(m);
                }
            }
        }

        /// <summary>
        /// 显示
        /// </summary>
        public virtual void show() {
            int dayButtonSize = m_dayButtons.size();
            for (int i = 0; i < dayButtonSize; i++) {
                DayButton dayButton = m_dayButtons.get(i);
                dayButton.setVisible(true);
            }
        }

        /// <summary>
        /// 更新布局方法
        /// </summary>
        public virtual void update() {
            onResetDiv(0);
            onResetDiv(1);
        }
    }
}
